org 0x7C00  ; set up start address of bootloader

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setup a stack and segment regs ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, ax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; read kernel from floppy disk ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    mov [bootdrive], dl ; boot drive stored by BIOS in DL.
                        ; we save it to [bootdrive] to play for safety.

load_kernel:
    xor ax, ax         ; mov ax, 0  => function "reset"
    int 0x13         
    jc load_kernel     ; trouble? try again

    mov bx, 0x8000     ; set up start address of kernel

    ; set parameters for reading function
    ; 8-bit-wise for better overview
    mov dl,[bootdrive] ; select boot drive
    mov al,10          ; read 10 sectors
    mov ch, 0          ; cylinder = 0
    mov cl, 2          ; sector   = 2
    mov dh, 0          ; head     = 0
    mov ah, 2          ; function "read" 
    int 0x13         
    jc load_kernel     ; trouble? try again

    ; show loading message
    mov si,loadmsg
    call print_string

;;;;;;;;;;;;;;;;;;
; jump to kernel ;
;;;;;;;;;;;;;;;;;;

    jmp 0x8000   ; address of kernel. "jmp bx" might also work.

;;;;;;;;;;;;;;;;;;;;;;;
; call "print_string" ;
;;;;;;;;;;;;;;;;;;;;;;;
 
print_string:
    mov ah, 0x0E      ; VGA BIOS fnct. 0x0E: teletype
.loop:   
    lodsb             ; grab a byte from SI
    test al, al       ; NUL?
    jz .done          ; if the result is zero, get out
    int 0x10          ; otherwise, print out the character!
    jmp .loop
.done:
    ret

;;;;;;;;
; data ;
;;;;;;;;

    bootdrive db 0    ; boot drive
    loadmsg db "bootloader message: loading kernel ...",13,10,0
    
    times 510-($-$$) hlt
    db 0x55
    db 0xAA

